#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include "MQTTClient.h"
#include <sys/msg.h>
#include "cJSON.h"

#define ADDRESS "tcp://172.31.36.70:1883"
#define CLIENTID "ExampleClientSub"
#define TOPIC_send "/app/data/up"
#define TOPIC_recv "/app/control/down"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
#define MAX_TEXT 512//队列文本大小
#define MSG_KEY 9999//队列密钥
#define SHM_KEY 1234//内存共享密钥
#define SEM_KEY 5678//内存信号锁密钥
#define SHM_SIZE 512//共享内存文本大小

struct shmseg {
    int written;
    int read_flags[2];
    char text[SHM_SIZE];
};//内存文本结构体

struct msgbuf {
    long mtype;
    char mtext[512];
};//队列文本结构体

volatile MQTTClient_deliveryToken deliveredtoken;
pthread_mutex_t client_mutex = PTHREAD_MUTEX_INITIALIZER;//连接用的锁
pthread_mutex_t global_send_mutex = PTHREAD_MUTEX_INITIALIZER;//数据交互用的锁内存到mq
pthread_mutex_t global_recv_mutex = PTHREAD_MUTEX_INITIALIZER;//数据交互用的锁mq到队列
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
int running = 1;
int mode=1;//mode=1是循环，mode=2是对比，mode=3是刷新
char global_send_buffer[512] = {0};//内存到mq
char global_recv_buffer[512] = {0};//mq到队列
char global_mode2_buffer[512] = {0};//mode2的中转
int command=0;//刷新命令

//// 信号量操作：P操作（等待）内存
void sem_wait(int semid) {
    struct sembuf sb = {0, -1, 0};
    semop(semid, &sb, 1);
}


//// 信号量操作：V操作（释放）内存
void sem_signal(int semid) {
    struct sembuf sb = {0, 1, 0};
    semop(semid, &sb, 1);
}

void delivered(void *context, MQTTClient_deliveryToken dt) // 回调函数查看消息是否被服务器接收到
{
    //printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int i;
    char *payloadptr;
    

    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: ");

    payloadptr = message->payload;
    for (i = 0; i < message->payloadlen; i++)
    {
        putchar(*payloadptr++);
    }
    putchar('\n');
    //
    // 拷贝 payload 为 null 结尾的字符串
            char *json_str = malloc(message->payloadlen + 1);
            memcpy(json_str, message->payload, message->payloadlen);
            json_str[message->payloadlen] = '\0';

            cJSON *root = cJSON_Parse(json_str);
            free(json_str);

            if (!root) {
                printf("JSON Parse Error!\n");
                MQTTClient_free(topicName);
                MQTTClient_freeMessage(&message);
                
            }

            cJSON *COM = cJSON_GetObjectItem(root, "COM");
            cJSON *MODE = cJSON_GetObjectItem(root, "MODE");

            if (COM) {
                printf("COM: %d\n", COM->valueint);
                if (COM->valueint == 1) {
                    command = 1;
                }
            }

            if (MODE) {
                printf("MODE: %d\n", MODE->valueint);
                mode = MODE->valueint;
            }
             pthread_mutex_lock(&global_recv_mutex);
           memset(global_recv_buffer, 0, sizeof(global_recv_buffer));

int copy_len = message->payloadlen;
if (copy_len >= sizeof(global_recv_buffer)) {
    copy_len = sizeof(global_recv_buffer) - 1;
}

memcpy(global_recv_buffer, message->payload, copy_len);
global_recv_buffer[copy_len] = '\0';  // 添加结尾

            pthread_mutex_unlock(&global_recv_mutex);

            cJSON_Delete(root);



    //
    
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
} // 回调函数处理接收到的数据

void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}
